package com.apes.scm.masterdata.finance.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.jpa.spec.model.Filter;
import com.apes.framework.jpa.spec.model.Group;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.express.FuncAlias;
import com.apes.scm.masterdata.finance.model.BankAccount;
import com.apes.scm.masterdata.finance.repository.BankAccountRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.DutyCenter;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 功能：
 *
 * @Auther: linwz
 * @Date: 2018/8/13 09:51
 */
@Service("bankAccountService")
public class BankAccountService extends DomainService {
    @Autowired
    BankAccountRepository bankAccountRepository;

    @Autowired
    private BankAccountDao bankAccountDao;

    @Autowired
    private DeptRepository deptRepository;

    /**
     * 保存
     *
     * @param request
     * @return
     */
    public BankAccount save(SimpleRequest request) {
        BankAccount bankAccount = request.getO(BankAccount.class);
        bankAccount.setPartyId(bankAccount.getCompany().getParty());
        return bankAccountRepository.saveAndFlush(bankAccount);
    }

    /***
     * 功能：修改
     * @param request
     * @return
     */
    public BankAccount update(SimpleRequest request) {
        String id = request.get("id");
        BankAccount bankAccount = request.getO(BankAccount.class);
        BankAccount tempBankAccount = bankAccountRepository.findOne(id);
        if (tempBankAccount == null) throw new RuntimeException("银行账户【" + id + "】在系统中不存在。");
        if (tempBankAccount.getVersion() != bankAccount.getVersion())
            throw new RuntimeException("记录已更新或已删除，请重新提交！");  // 用于判断当前版本是否被修改
        return bankAccountRepository.saveAndFlush(bankAccount);
    }

    /***
     * 功能： 删除
     * @param request
     * @return
     */
    public String delete(SimpleRequest request) {
        String id = request.get("id");
        BankAccount bankAccount = request.getO(BankAccount.class);
        BankAccount tempBankAccount = bankAccountRepository.findOne(id);
        if (tempBankAccount == null) throw new RuntimeException("银行账户【" + id + "】在系统中不存在。");
        if (tempBankAccount.getVersion() != bankAccount.getVersion()) throw new RuntimeException("记录已更新或已删除，请重新提交！");
        bankAccountRepository.delete(bankAccount);
        return "删除成功";
    }

    /**
     * 解析前端参数
     *
     * @param array filter 参数，解析日期格式
     * @return
     */
    public JSONObject parseCondition(JSONArray array) {
        JSONObject model = new JSONObject();
        array.forEach(v -> {
            JSONObject filter = (JSONObject) v;
            model.put(filter.getString("field"), filter.get("value"));
        });
        return model;
    }


    private Map findAllRelate(SimpleRequest request) {
        JSONObject json = request.getJO();
        JSONObject param = parseCondition(json.getJSONArray("condition"));

        JSONArray all = bankAccountDao.findBankAccount(param, request.getPostId(), request.get("page"), request.get("size"));
        Object count = bankAccountDao.findBankAccountCount(param, request.getPostId());
        JSONObject result = new JSONObject();
        result.put("content", all);
        result.put("total", ((JSONObject) ((JSONArray) count).get(0)).get("COUNT"));
        result.put("pages", ((JSONObject) ((JSONArray) count).get(0)).get("COUNT"));
        return result;
    }

    public List<BankAccount> findAllRelateNoPage(SimpleRequest request) {
        Group group = findAllCore(request);
        return bankAccountRepository.findAll(group.build(true));
    }

    public List<BankAccount> findByCompanyAndValid(SimpleRequest request) {
        JSONObject jo = request.getJO();
        Dept dept = deptRepository.findOne(jo.get("dept").toString());
        return bankAccountRepository.findByCompanyAndValid(dept.getCompany().getId());
    }

    public List<BankAccount> findBankAccountByCompany(SimpleRequest request) {
        JSONObject jo = request.getJO();
        return bankAccountRepository.findByCompanyAndValid(jo.get("company").toString());
    }

    public List<BankAccount> findByCompanyAndPrepareSign(SimpleRequest request) {
        JSONObject jo = request.getJO();
        Dept dept = deptRepository.findOne(jo.get("dept").toString());
        String company = invoke("fn.contract.findByCompany", mapper("company", dept.getCompany().getId()));
        return bankAccountRepository.findByCompanyAndPrepareSign(company);
    }

    public Page<BankAccount> findAllByCompany(SimpleRequest request) {
        JSONObject jo = request.getJO();
        if (jo.get("key") != null) {
            return bankAccountRepository.findByCompanyAndKey(jo.get("company").toString(), jo.get("key").toString(), PageRequest.of(request.get("page"), request.get("size")));
        }
        return bankAccountRepository.findByCompany(jo.get("company").toString(), PageRequest.of(request.get("page"), request.get("size")));
    }

    /***
     * 抽取的公共逻辑
     */
    private Group findAllCore(SimpleRequest request) {
        Group group = JpaDsl.getGroup(request);

        List<Filter> filters = group.getFilters();

        // 筛选出对应的id， 用于匹配 第三方单号 原始单号 上游单号
        Filter filter = filters.stream().filter(item -> item.getField().equals("id")).findFirst().orElse(null);

        if (filter != null) {
            filters.remove(filter); // 移除当前选项
            group.addGroup(createIdGroup(filter));
        }
        return group;
    }

    /***
     * 构建订单 Group
     */
    private Group createIdGroup(Filter filter) {
        Group idGroup = new Group();
        idGroup.setOperator("or");
        idGroup.addFilters(
                JpaDsl.toFilter(
                        "bank.name", "LIKE", filter.getValue(),
                        "bank.id", "EQ", filter.getValue(),
                        "id", "EQ", filter.getValue(),
                        "name", "LIKE", filter.getValue(),
                        "accountId", "EQ", filter.getValue()
                )
        );
        return idGroup;
    }

    /**
     * 通过部门获取成本中心
     */
    @FuncAlias(name = "getBankAccount")
    public BankAccount getBankAccount(BankAccount bankAccount) {
        if (bankAccount == null) throw new RuntimeException(" 银行账户不存在！");
        return bankAccount;
    }
}
